﻿using DevExpress.XtraEditors;
using DevExpress.XtraEditors.Controls;
using DevExpress.XtraEditors.Calendar;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BW.Mes.WinForms.Production.ProductionDate
{
    public partial class ProductionDateForm : DevExpress.XtraEditors.XtraForm
    {
        // 存储生产日期和对应的任务信息
        private Dictionary<DateTime, string> productionTasks = new Dictionary<DateTime, string>();

        // 存储日期类型信息（0=休，1=班）
        private Dictionary<DateTime, int> dateTypes = new Dictionary<DateTime, int>();

        // API基础URL
        private readonly string apiBaseUrl = "https://localhost:7223";
        private readonly HttpClient httpClient;

        // 颜色定义
        private readonly Color workDayColor = Color.FromArgb(0, 192, 0); // 绿色，表示上班
        private readonly Color restDayColor = Color.FromArgb(231, 76, 60); // 红色，表示休息

        public ProductionDateForm()
        {
            InitializeComponent();

            // 初始化HttpClient
            httpClient = new HttpClient();
            httpClient.BaseAddress = new Uri(apiBaseUrl);
            httpClient.DefaultRequestHeaders.Accept.Clear();
            httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

            // 设置日历控件的初始化
            InitializeCalendar();

            // 注册事件
            this.Load += ProductionDateForm_Load;
            this.calendarControl.MouseUp += CalendarControl_MouseUp;
            this.calendarControl.EditValueChanged += CalendarControl_EditValueChanged;
            this.calendarControl.CustomDrawDayNumberCell += CalendarControl_CustomDrawDayNumberCell;
        }

        /// <summary>
        /// 初始化日历控件
        /// </summary>
        private void InitializeCalendar()
        {
            // 设置当前日期为选中日期
            calendarControl.DateTime = DateTime.Today;

            // 设置周数显示为false，不显示周数
            calendarControl.ShowWeekNumbers = false;

            // 设置是否显示今天按钮
            calendarControl.ShowTodayButton = true;

            // 设置一周的第一天是周一
            calendarControl.FirstDayOfWeek = DayOfWeek.Monday;

            // 设置是否显示清除按钮
            calendarControl.ShowClearButton = false;

            // 设置是否显示标题
            calendarControl.ShowHeader = true;

            // 放大日历视图
            calendarControl.CalendarAppearance.DayCell.Font = new Font(calendarControl.CalendarAppearance.DayCell.Font.FontFamily, 12f, FontStyle.Regular);
            calendarControl.CalendarAppearance.DayCellSpecial.Font = new Font(calendarControl.CalendarAppearance.DayCellSpecial.Font.FontFamily, 12f, FontStyle.Bold);
            calendarControl.CalendarAppearance.WeekDay.Font = new Font(calendarControl.CalendarAppearance.WeekDay.Font.FontFamily, 12f, FontStyle.Bold);
            calendarControl.CalendarAppearance.WeekNumber.Font = new Font(calendarControl.CalendarAppearance.WeekNumber.Font.FontFamily, 12f, FontStyle.Regular);
            calendarControl.CalendarAppearance.Header.Font = new Font(calendarControl.CalendarAppearance.Header.Font.FontFamily, 14f, FontStyle.Bold);

            // 设置日历单元格大小
            calendarControl.CellSize = new Size(60, 60);
        }

        /// <summary>
        /// 窗体加载事件
        /// </summary>
        private async void ProductionDateForm_Load(object sender, EventArgs e)
        {
            // 在这里加载特定日期的生产数据
            await LoadProductionDateData(DateTime.Now.Year, DateTime.Now.Month);

            // 刷新日历显示
            calendarControl.Refresh();
        }

        /// <summary>
        /// 日期变更事件
        /// </summary>
        private async void CalendarControl_EditValueChanged(object sender, EventArgs e)
        {
            // 获取当前选中的日期
            DateTime selectedDate = calendarControl.DateTime;

            // 如果月份变化，重新加载数据
            if (!dateTypes.Any() ||
                (dateTypes.Keys.First().Year != selectedDate.Year ||
                 dateTypes.Keys.First().Month != selectedDate.Month))
            {
                await LoadProductionDateData(selectedDate.Year, selectedDate.Month);
                calendarControl.Refresh();
            }
        }

        /// <summary>
        /// 自定义绘制日历单元格
        /// </summary>
        private void CalendarControl_CustomDrawDayNumberCell(object sender, CustomDrawDayNumberCellEventArgs e)
        {
            try
            {
                // 获取当前单元格的日期
                DateTime cellDate = e.Date.Date;

                // 检查是否有日期类型数据
                if (dateTypes.TryGetValue(cellDate, out int type))
                {
                    // 完全接管单元格的绘制
                    e.Handled = true;

                    // 首先绘制背景
                    Color backColor;
                    Color borderColor = Color.Transparent;

                    // 如果是选中的日期，使用特殊的背景色
                    bool isSelected = cellDate == calendarControl.DateTime.Date;
                    if (isSelected)
                    {
                        backColor = Color.FromArgb(180, 200, 240);
                        borderColor = Color.FromArgb(100, 120, 200);

                        // 绘制背景和边框
                        using (SolidBrush brush = new SolidBrush(backColor))
                        {
                            e.Graphics.FillRectangle(brush, e.Bounds);
                        }

                        using (Pen pen = new Pen(borderColor))
                        {
                            e.Graphics.DrawRectangle(pen, e.Bounds.X, e.Bounds.Y, e.Bounds.Width - 1, e.Bounds.Height - 1);
                        }
                    }
                    else
                    {
                        // 非选中状态使用默认背景
                        backColor = SystemColors.Window;

                        // 绘制背景
                        using (SolidBrush brush = new SolidBrush(backColor))
                        {
                            e.Graphics.FillRectangle(brush, e.Bounds);
                        }
                    }

                    // 绘制日期数字
                    Font dayFont = new Font("Arial", 14, FontStyle.Regular);
                    Color dayColor = cellDate.Month == calendarControl.DateTime.Month ?
                                    Color.Black : Color.Gray;

                    // 日期数字位置（居中偏左）
                    Rectangle dayRect = new Rectangle(
                        e.Bounds.Left + 8,
                        e.Bounds.Top + 8,
                        e.Bounds.Width / 2,
                        e.Bounds.Height / 2);

                    using (StringFormat sf = new StringFormat())
                    {
                        sf.Alignment = StringAlignment.Near;
                        sf.LineAlignment = StringAlignment.Near;
                        e.Graphics.DrawString(cellDate.Day.ToString(), dayFont, new SolidBrush(dayColor), dayRect, sf);
                    }

                    // 在单元格右上角添加"班"或"休"标记
                    Rectangle textRect = new Rectangle(
                        e.Bounds.Right - 25,
                        e.Bounds.Top + 2,
                        22,
                        22);

                    if (type == 1) // 班
                    {
                        e.Graphics.DrawString("班", new Font("宋体", 10, FontStyle.Bold), new SolidBrush(workDayColor), textRect,
                            new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
                    }
                    else // 休
                    {
                        e.Graphics.DrawString("休", new Font("宋体", 10, FontStyle.Bold), new SolidBrush(restDayColor), textRect,
                            new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });
                    }

                    // 如果有备注，添加提示图标
                    if (productionTasks.TryGetValue(cellDate, out string remark) && !string.IsNullOrEmpty(remark))
                    {
                        Rectangle noteRect = new Rectangle(
                            e.Bounds.Left + 4,
                            e.Bounds.Bottom - 22,
                            20,
                            20);

                        e.Graphics.DrawString("📝", new Font("宋体", 10, FontStyle.Bold), Brushes.Black, noteRect);
                    }
                }
                else
                {
                    // 对于没有特殊标记的日期，使用默认绘制
                    e.Handled = false;

                    // 周末特殊处理 - 只用浅色标记，不填充整个背景
                    if (cellDate.DayOfWeek == DayOfWeek.Saturday || cellDate.DayOfWeek == DayOfWeek.Sunday)
                    {
                        // 在日期右侧添加一个小标记
                        Rectangle weekendRect = new Rectangle(
                            e.Bounds.Right - 10,
                            e.Bounds.Top + 3,
                            8,
                            8);
                        e.Graphics.FillRectangle(new SolidBrush(Color.LightBlue), weekendRect);
                    }
                }
            }
            catch (Exception ex)
            {
                // 在这里记录错误，但不显示消息框，避免影响用户体验
                System.Diagnostics.Debug.WriteLine($"绘制日历单元格时出错: {ex.Message}");
            }
        }

        /// <summary>
        /// 从API加载生产日期数据
        /// </summary>
        private async Task LoadProductionDateData(int year, int month)
        {
            try
            {
                // 清空现有数据
                dateTypes.Clear();
                productionTasks.Clear();

                // 构建API请求URL
                string endpoint = $"/api/ProductionDate/GetByMonth?Year={year}&Month={month:D2}";

                // 发送请求
                HttpResponseMessage response = await httpClient.GetAsync(endpoint);

                if (response.IsSuccessStatusCode)
                {
                    // 读取响应内容
                    string responseContent = await response.Content.ReadAsStringAsync();

                    try
                    {
                        // 首先解析为JObject，检查API返回的格式
                        JObject jsonResponse = JObject.Parse(responseContent);

                        // 检查API返回是否成功
                        if (jsonResponse["Success"] != null && jsonResponse["Success"].Value<bool>())
                        {
                            // 获取Data字段中的数据
                            if (jsonResponse["Data"] != null)
                            {
                                try
                                {
                                    // 直接处理JArray，避免反序列化问题
                                    JArray dataArray = jsonResponse["Data"] as JArray;
                                    if (dataArray != null)
                                    {
                                        foreach (JObject item in dataArray)
                                        {
                                            // 手动提取字段，避免类型转换问题
                                            string dateStr = item["Date"]?.ToString();
                                            int? type = item["Type"]?.Value<int>();
                                            string remark = item["Remark"]?.ToString();

                                            if (!string.IsNullOrEmpty(dateStr) && type.HasValue &&
                                                DateTime.TryParse(dateStr, out DateTime date))
                                            {
                                                // 存储日期类型（0=班，1=休）
                                                dateTypes[date.Date] = type.Value;

                                                // 如果有备注，添加到任务信息中
                                                if (!string.IsNullOrEmpty(remark) && remark.ToLower() != "null")
                                                {
                                                    productionTasks[date.Date] = remark;
                                                }
                                            }
                                        }
                                    }
                                }
                                catch (Exception ex)
                                {
                                    XtraMessageBox.Show($"解析日期数据时出错: {ex.Message}", "数据解析错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                }
                            }
                        }
                        else
                        {
                            // API返回失败
                            string errorMessage = jsonResponse["Message"]?.Value<string>() ?? "未知错误";
                            XtraMessageBox.Show($"获取生产日期数据失败: {errorMessage}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    catch (Exception ex)
                    {
                        XtraMessageBox.Show($"解析JSON响应时出错: {ex.Message}", "JSON解析错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    XtraMessageBox.Show($"获取生产日期数据失败: {response.StatusCode}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show($"加载生产日期数据时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 鼠标释放事件，用于处理右键菜单
        /// </summary>
        private void CalendarControl_MouseUp(object sender, MouseEventArgs e)
        {
            // 如果是右键点击
            if (e.Button == MouseButtons.Right)
            {
                // 获取当前日期
                DateTime clickedDate = calendarControl.DateTime;

                // 创建右键菜单
                ContextMenuStrip menu = new ContextMenuStrip();

                // 添加菜单项 - 编辑
                ToolStripMenuItem editItem = new ToolStripMenuItem("编辑");
                editItem.Click += (s, args) => EditProductionDate(clickedDate);

                // 添加菜单项 - 设置为上班
                ToolStripMenuItem setWorkDay = new ToolStripMenuItem("设置为上班");
                setWorkDay.Click += async (s, args) => await SetDateType(clickedDate, 1);

                // 添加菜单项 - 设置为休息
                ToolStripMenuItem setRestDay = new ToolStripMenuItem("设置为休息");
                setRestDay.Click += async (s, args) => await SetDateType(clickedDate, 0);

                // 添加菜单项 - 添加备注
                ToolStripMenuItem addRemark = new ToolStripMenuItem("添加备注");
                addRemark.Click += (s, args) => AddProductionTask(clickedDate);

                // 添加菜单项 - 查看详情
                ToolStripMenuItem viewDetails = new ToolStripMenuItem("查看详情");
                viewDetails.Enabled = dateTypes.ContainsKey(clickedDate.Date) || productionTasks.ContainsKey(clickedDate.Date);
                viewDetails.Click += (s, args) => ViewDateDetails(clickedDate);

                // 添加菜单项到菜单
                menu.Items.Add(editItem);
                menu.Items.Add(new ToolStripSeparator());
                menu.Items.Add(setWorkDay);
                menu.Items.Add(setRestDay);
                menu.Items.Add(new ToolStripSeparator());
                menu.Items.Add(addRemark);
                menu.Items.Add(viewDetails);

                // 显示菜单
                menu.Show(calendarControl, e.Location);
            }
        }

        /// <summary>
        /// 编辑生产日期
        /// </summary>
        private async void EditProductionDate(DateTime date)
        {
            try
            {
                // 获取当前日期的类型，如果不存在则默认为上班(1)
                int currentType = dateTypes.TryGetValue(date.Date, out int type) ? type : 1;

                // 创建并显示编辑对话框
                using (var form = new AddProdectionDateForm())
                {
                    // 设置初始值
                    form.SelectedDate = date;
                    form.DateType = currentType;

                    // 显示对话框
                    if (form.ShowDialog() == DialogResult.OK)
                    {
                        // 用户点击了确定，保存设置
                        await SetDateType(form.SelectedDate, form.DateType);
                    }
                }
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show($"编辑生产日期时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 设置日期类型
        /// </summary>
        private async Task SetDateType(DateTime date, int type)
        {
            try
            {
                // 构建API请求URL和数据
                string endpoint = "/api/ProductionDate/SetDateType";

                var data = new
                {
                    Date = date.ToString("yyyy-MM-ddT00:00:00"),
                    Type = type,
                    Remark = productionTasks.TryGetValue(date.Date, out string remark) ? remark : null
                };

                // 序列化数据
                string jsonContent = JsonConvert.SerializeObject(data);
                HttpContent content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

                // 发送请求
                HttpResponseMessage response = await httpClient.PostAsync(endpoint, content);

                if (response.IsSuccessStatusCode)
                {
                    // 读取响应内容
                    string responseContent = await response.Content.ReadAsStringAsync();

                    // 解析响应
                    JObject jsonResponse = JObject.Parse(responseContent);

                    if (jsonResponse["Success"] != null && jsonResponse["Success"].Value<bool>())
                    {
                        // 更新本地数据
                        dateTypes[date.Date] = type;

                        // 刷新日历显示
                        calendarControl.Refresh();

                        XtraMessageBox.Show($"已成功将 {date:yyyy年MM月dd日} 设置为{(type == 1 ? "上班" : "休息")}日",
                            "设置成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        string errorMessage = jsonResponse["Message"]?.Value<string>() ?? "未知错误";
                        XtraMessageBox.Show($"设置日期类型失败: {errorMessage}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    XtraMessageBox.Show($"设置日期类型失败: {response.StatusCode}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                XtraMessageBox.Show($"设置日期类型时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// 添加生产任务（备注）
        /// </summary>
        private async void AddProductionTask(DateTime date)
        {
            // 使用输入框获取任务信息
            string taskInfo = "";

            // 如果已有备注，显示在输入框中
            if (productionTasks.TryGetValue(date.Date, out string existingRemark))
            {
                taskInfo = existingRemark;
            }

            // 使用简单的输入对话框
            using (Form inputForm = new Form())
            {
                inputForm.Width = 300;
                inputForm.Height = 150;
                inputForm.Text = "输入备注信息";
                inputForm.StartPosition = FormStartPosition.CenterParent;

                TextBox textBox = new TextBox();
                textBox.Multiline = true;
                textBox.Left = 10;
                textBox.Top = 10;
                textBox.Width = 280;
                textBox.Height = 80;
                textBox.Text = taskInfo;

                Button okButton = new Button();
                okButton.Text = "确定";
                okButton.Left = 120;
                okButton.Top = 90;
                okButton.DialogResult = DialogResult.OK;

                inputForm.Controls.Add(textBox);
                inputForm.Controls.Add(okButton);
                inputForm.AcceptButton = okButton;

                if (inputForm.ShowDialog() == DialogResult.OK)
                {
                    taskInfo = textBox.Text;

                    try
                    {
                        // 构建API请求URL和数据
                        string endpoint = "/api/ProductionDate/SetDateRemark";

                        var data = new
                        {
                            Date = date.ToString("yyyy-MM-ddT00:00:00"),
                            Type = dateTypes.TryGetValue(date.Date, out int type) ? type : 0,
                            Remark = taskInfo
                        };

                        // 序列化数据
                        string jsonContent = JsonConvert.SerializeObject(data);
                        HttpContent content = new StringContent(jsonContent, Encoding.UTF8, "application/json");

                        // 发送请求
                        HttpResponseMessage response = await httpClient.PostAsync(endpoint, content);

                        if (response.IsSuccessStatusCode)
                        {
                            // 读取响应内容
                            string responseContent = await response.Content.ReadAsStringAsync();

                            // 解析响应
                            JObject jsonResponse = JObject.Parse(responseContent);

                            if (jsonResponse["Success"] != null && jsonResponse["Success"].Value<bool>())
                            {
                                // 更新本地数据
                                if (string.IsNullOrWhiteSpace(taskInfo))
                                {
                                    productionTasks.Remove(date.Date);
                                }
                                else
                                {
                                    productionTasks[date.Date] = taskInfo;
                                }

                                // 刷新日历显示
                                calendarControl.Refresh();

                                XtraMessageBox.Show($"已成功为 {date:yyyy年MM月dd日} 设置备注",
                                    "设置成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                            }
                            else
                            {
                                string errorMessage = jsonResponse["Message"]?.Value<string>() ?? "未知错误";
                                XtraMessageBox.Show($"设置备注失败: {errorMessage}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }
                        }
                        else
                        {
                            XtraMessageBox.Show($"设置备注失败: {response.StatusCode}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                    }
                    catch (Exception ex)
                    {
                        XtraMessageBox.Show($"设置备注时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        /// <summary>
        /// 查看日期详情
        /// </summary>
        private void ViewDateDetails(DateTime date)
        {
            string typeInfo = dateTypes.TryGetValue(date.Date, out int type) ? (type == 1 ? "上班" : "休息") : "未设置";
            string remarkInfo = productionTasks.TryGetValue(date.Date, out string remark) ? remark : "无";

            XtraMessageBox.Show($"日期: {date:yyyy年MM月dd日}\n类型: {typeInfo}\n备注: {remarkInfo}",
                "生产日期详情", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        /// <summary>
        /// 生产日期数据模型
        /// </summary>
        private class ProductionDateModel
        {
            public long Id { get; set; }  // 使用long而不是int，避免整数溢出
            public string Date { get; set; }
            public int Type { get; set; }  // 0=班，1=休
            public string Remark { get; set; }
        }

        /// <summary>
        /// API响应模型
        /// </summary>
        private class ApiResponse<T>
        {
            public bool Success { get; set; }
            public string Message { get; set; }
            public T Data { get; set; }
        }
    }
}